#include <cppunit/config/SourcePrefix.h>

#include "Parser.h"
#include "TestParser.h"

#include <iostream>
#include <string>

void ParserTest::setUp()
{
	cout << "Test Parser setUp()\n";
}
void ParserTest::tearDown()
{}

//Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION(ParserTest);
Parser *p;
void ParserTest::testConstructor(){
	PKB* pkb = PKB::getInstance();
	p = new Parser(pkb);
}

std::string sourceCode1 =	"procedure First {\n"
								"x = 2;\n"
								"y = x;\n"
							"}\n";
//std::string sourceCode1 = "procedure First {""x = 2;""y = x;""}";
std::string sourceCode2 =	"procedure       second {\n"
								"x = 1;\n"
								"x=    3; \n"
								"y=5\n"		// no semi-colon here
							"}\n";
std::string sourceCode3 =	"procedure source6 {\n"
								"x = 012;\n"
								"i = 5 + x;\n"
								"while i {\n"
									"x = x + 2 + z;\n"
									"i = x + 1;\n"
									"while x {\n"
										"i = 5;\n"
										"x = y + z; }}\n"
								"x = x+ x + y +zz;\n"
								"u = x + y;\n"
								"while u {\n"
									"while x {\n"
										"x = u + 1; }}\n"
								"x = y; }";
std::string sourceCode4 =	"procedure procnametest {\n"
								"x = 0;\n"
								"i = 5 + x;\n"
								"while i {\n"
								"    x = x + 2 + z;\n"
								"  i = x + 1;\n"
							"  while x {\n"
							"      i = 5;\n"
							"       x = y + z; }}\n"
							"x = x+ x + y +zz; }\n";
std::string sourceCode5 =	"procedure fifth5 {\n"
							"dog1 = cat2;\n"
							"while dog1 {\n"
								"dog1 = bird3;\n"
								"while dog1 {\n"
								   "dog1 = fish4; } }\n"  
							"}";
std::string sourceCode7 = "procedure source7 {\n"
							"x = 0;\n"
							"i = 5 + x;\n"
						   "while i {\n"
								"x = x + 2 + z;\n"
								"i = x + 1;\n"
								"while x {\n"
									"i = 5;\n"
									"x = y + z; }}\n"
							"x = x+ x + y +zz;\n"
							"u = x + y;\n"
							"while u {\n"
							   " while x {\n"
									"x = u + 1; }}\n"
						   "x = x + x + y + z; }\n";


void ParserTest::testProgram(){
	std::cout<<"\n\n\nENTERED PARSERTEST::TESTPROGRAM\n\n\n";
	PKB *pkb = new PKB();
	p = new Parser(pkb);

	std::cout<<"\n\n\npass 1\n\n\n";
	std::cout<<sourceCode1<<endl;
	CPPUNIT_ASSERT_EQUAL(true, p->executeSrc(sourceCode1));
	CPPUNIT_ASSERT_EQUAL(true, pkb->isLineModifies(1,1));
	CPPUNIT_ASSERT_EQUAL(true, pkb->isLineModifies(2,2));

	//pkb->~PKB();
	//pkb = PKB::getInstance();
	//p = new Parser(pkb);
	pkb = new PKB();
	p = new Parser(pkb);
	std::cout<<"\n\n\npass 2\n\n\n";
	CPPUNIT_ASSERT_EQUAL(false, p->executeSrc(sourceCode2));

	pkb = new PKB();
	p = new Parser(pkb);
	std::cout<<"\n\n\npass 3\n\n\n";
	CPPUNIT_ASSERT_EQUAL(true, p->executeSrc(sourceCode3));

	pkb = new PKB();
	p = new Parser(pkb);
	std::cout<<"\n\n\npass 4\n\n\n";
	CPPUNIT_ASSERT_EQUAL(true, p->executeSrc(sourceCode4));

	pkb = new PKB();
	p = new Parser(pkb);
	std::cout<<"\n\n\npass 5\n\n\n";
	CPPUNIT_ASSERT_EQUAL(true, p->executeSrc(sourceCode5));

	pkb = new PKB();
	p = new Parser(pkb);
	std::cout<<"\n\n\npass 7\n\n\n";
	CPPUNIT_ASSERT_EQUAL(true, p->executeSrc(sourceCode7));

	std::cout<<"\n\n\nEXITED PARSERTEST::TESTPROGRAM\n\n\n";
}

void ParserTest::testFollows(){

}

void ParserTest::testParents(){

}

void ParserTest::testModifies(){

}

void ParserTest::testUses(){

}